﻿#region Copyright information
// 
// Copyright © 2012-2013 Yongkee Cho. All rights reserved.
// 
// This code is a part of the SubnetworkToolkit and governed under the terms of the
// GNU Lesser General  Public License (LGPL) version 2.1 which accompanies this distribution.
// For more information on the LGPL, please visit http://bol.codeplex.com/license.
// 
// - Filename: Program.cs
// - Author: Yongkee Cho
// - Email: yongkeecho@outlook.com
// - Date Created: 2013-01-30 2:55 PM
// - Last Modified: 2013-01-30 3:21 PM
// 
#endregion
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using BOL.Collections;
using BOL.IO;
using CommandLine;
using SubnetworkToolkit.IO;
using SubnetworkToolkit.Data;

namespace SubnetworkToolkit.Export
{
    static class Program
    {
        static void Main(string[] args)
        {
            var options = new Options();

            try
            {
                // parse arguments
                var parser = new CommandLineParser(new CommandLineParserSettings(Console.Error));
                parser.ParseArguments(args, options);

                if (args.Length == 0 || args[0] == "-h")
                    Console.Error.Write(options.GetUsage());
                else
                {
                    // read gmt file
                    var gmt = options.GmtFile;
                    var gr = new GmtReader(gmt);
                    var geneSets = gr.Read();
                    gr.Close();

                    // get unique gene ids
                    var genes = geneSets.SelectMany(geneSet => geneSet.Genes).Distinct().ToList();

                    // read property files
                    var propertyFiles = options.PropertyFiles;
                    foreach (var propertyFile in propertyFiles)
                    {
                        var tmp = propertyFile.Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                        
                        var dtr = new DelimitedTextReader(tmp[1], ",");
                        var property = dtr.Read().ToDictionary(line => Int32.Parse(line[0]), line => Double.Parse(line[1]));
                        genes.ForEach(x => x.Property.Add(tmp[0], property[x.Id]));
                    }

                    // read important genes
                    var importantGenes = options.ImportantGenes;
                    var iid = importantGenes.Select(Int32.Parse).ToList();
                    foreach (var gene in genes)
                        gene.Property.Add("Special", iid.Contains(gene.Id) ? 1 : 0);

                    // count 
                    var geneCount = new Dictionary<int, double>();
                    foreach (var gene in genes)
                    {
                        if (geneCount.ContainsKey(gene.Id))
                            geneCount[gene.Id]++;
                        else
                            geneCount.Add(gene.Id, 1);
                    }
                    genes.ForEach(x => x.Property.Add("Count", geneCount[x.Id]));

                    // annotations
                    var annotations = new AnnotationsHuman();
                    var temp = annotations.Symbol2Id.ToList();

                    var id2Sym = new Dictionary<int, string>();
                    foreach (var t in temp.Where(t => !id2Sym.ContainsKey(t.Id)))
                        id2Sym.Add(t.Id, t.Symbol);
                    genes.ForEach(x => x.Symbol = id2Sym[x.Id]);

                    // integrate all
                    var hgr = new GeneRelationsHuman();
                    var temp1 = hgr.Relations.ToList();

                    var name = options.Name;
                    var graphMlFile = options.GraphMlFile;
                    var geneDic = genes.ToDictionary(x => x.Id, x => x);
                    var interactions = temp1.Where(x => geneDic.ContainsKey(x.SourceId) && geneDic.ContainsKey(x.TargetId)).ToList();
                    var gml = new GraphMlWriter(
                        graphMlFile,
                        name,
                        genes,
                        interactions.Select(x => new Tuple<Gene, Gene, int>(geneDic[x.SourceId], geneDic[x.TargetId], new BitArray(new [] { (int)x.Pattern }).CountBits())).ToList()
                    );

                    gml.Write();
                    gml.Close();
                }
            }
            catch (Exception ex)
            {
                Console.Error.Write(ex.Message);
            }
        }
    }
}
